﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Web;
using System.Web.Hosting;
using Dukou.WebSiteDesigner.Domain;
using Dukou.Web;

namespace Dukou.WebSiteDesigner.Web
{
    public class DbVirtualPathProvider : VirtualPathProvider, IGlobalModule
    {
        private static string VirtualPathKey = "/views/shared/";
        private static string ViewExtension = ".cshtml";

        private static ISet<string> ReservedViews = new HashSet<string>()
        {
            "_viewstart",
            "_layout"
        };

        public static IPageDesigner PageDesigner { get; set; }

        public override bool FileExists(string virtualPath)
        {
            string page = this.FindPage(virtualPath);
            if (string.IsNullOrEmpty(page))
            {
                return base.FileExists(virtualPath);
            }

            return true;
        }

        public override VirtualFile GetFile(string virtualPath)
        {
            string page = this.FindPage(virtualPath);
            if (string.IsNullOrEmpty(page))
            {
                return base.GetFile(virtualPath);
            }

            byte[] data = System.Text.Encoding.UTF8.GetBytes(page);

            return new DbVirtualFile(virtualPath, data);
        }

        public override System.Web.Caching.CacheDependency GetCacheDependency(string virtualPath, System.Collections.IEnumerable virtualPathDependencies, DateTime utcStart)
        {
            if (virtualPath.ToLower().Contains(VirtualPathKey))
            {
                return null;
            }
            return base.GetCacheDependency(virtualPath, virtualPathDependencies, utcStart);
        }

        public override string GetFileHash(string virtualPath, System.Collections.IEnumerable virtualPathDependencies)
        {
            if (virtualPath.ToLower().Contains(VirtualPathKey))
            {
                return virtualPath;
            }

            return base.GetFileHash(virtualPath, virtualPathDependencies);
        }

        private string FindPage(string virtualPath)
        {
            string path = virtualPath.ToLower();
            int start = path.IndexOf(VirtualPathKey);
            int end = path.IndexOf(ViewExtension);
            if (start >= 0 && path.Length - end == ViewExtension.Length)
            {
                var key = path.Substring(start + VirtualPathKey.Length, end - VirtualPathKey.Length - start);
                if (!ReservedViews.Contains(key))
                {
                    if (key.StartsWith("get_page/"))
                    {
                        key = key.Substring(9);
                        if (string.IsNullOrEmpty(key))
                        {
                            return null;
                        }

                        if (!ReservedViews.Contains(key))
                        {
                            Int64 pageId = Int64.Parse(key);
                            Page page = PageDesigner.FindById(pageId);
                            return page == null ? null : page.Html;
                        }
                    }
                }
            }

            return null;
        }

        public string Name
        {
            get { return "DbVirtualPathProvider"; }
        }

        public void Initialize(HttpApplication application, Spring.Context.IApplicationContext appContext)
        {
            DbVirtualPathProvider.PageDesigner = appContext.GetObject("PageDesigner") as IPageDesigner;
        }
    }
}